package com.pucong.gitee.database.backup.codeHelper;

import com.pucong.gitee.database.backup.common.entity.codeHelper.TableColumn;
import com.pucong.gitee.database.backup.common.entity.codeHelper.TableColumnEnum;
import freemarker.template.Template;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 自动生成代码工具
 *
 * @author pucong
 * @company hchl.org
 * @create 2019-03-30
 */
public class CodeGenerateUtils {

    private static Logger logger = LoggerFactory.getLogger(CodeGenerateUtils.class);

    public static void main(String[] args) {
        CodeGenerateUtils codeGenerateUtils = new CodeGenerateUtils();
        codeGenerateUtils.setAuthor("pucong");
        //设置模块路径
        codeGenerateUtils.setModule_path("com.pucong.gitee.database.backup");
        //设置业务代码包目录
        codeGenerateUtils.setBusiness_package_folder("business.database");
        //设置是实体类包目录
        codeGenerateUtils.setEntity_package_folder("common.entity");
        //设置是枚举类包目录
        codeGenerateUtils.setEnum_folder("common.selfenum");
        //设置表名称
        codeGenerateUtils.setTable_name("AUTO_SEARCH_SQL_INFO");
        //设置实体类名称
        codeGenerateUtils.setChange_table_name("SearchSqlInfo");
        //设置实体类注释
        codeGenerateUtils.setTableAnnotation("");
        //生成实体类
        codeGenerateUtils.setRunEntity(true);
        //生成控制层
        codeGenerateUtils.setRunController(true);
        //生成mapper
        codeGenerateUtils.setRunMapper(true);
        //生成业务层
        codeGenerateUtils.setRunService(true);
        //生成转换器
        codeGenerateUtils.setRunBeanConvert(true);
        //生成web
        codeGenerateUtils.setRunWebVue(true);

        //开始生成
        codeGenerateUtils.generate();
    }

    /**
     * 作者
     */
    @Setter
    private String author = "yuan";

    /**
     * 原表名
     */
    @Setter
    private String table_name = "financial_sys_datarole_filter";

    /**
     * 实体类名
     */
    @Setter
    private String change_table_name = "DataRoleFilter";

    /**
     * 业务代码目录
     * 以 / 分隔或者以 . 分隔；如 system/user 或者 system.user
     */
    @Setter
    private String business_package_folder = "system.datarole";

    /**
     * 不填则使用表注释
     */
    @Setter
    private String tableAnnotation = "数据角色过滤条件关联关系";

    /**
     * 不填则使用表注释
     */
    @Setter
    private String serviceName = "integrate-service";

    /**
     * 执行生成控制层
     */
    @Setter
    private Boolean runController = true;

    /**
     * 执行生成业务层
     */
    @Setter
    private Boolean runService = true;

    /**
     * 执行生成mapper层
     */
    @Setter
    private Boolean runMapper = true;

    /**
     * 执行生成实体层
     */
    @Setter
    private Boolean runEntity = true;

    /**
     * 执行生成转换器
     */
    @Setter
    private Boolean runBeanConvert = true;

    /**
     * 执行生成转换器
     */
    @Setter
    private Boolean runWebVue = true;

    /**
     * 模块路径
     */
    @Setter
    private String module_path = "com.pucong.gitee.database.backup";

    /**
     * 实体类目录
     */
    @Setter
    private String entity_package_folder = "com.pucong.gitee.database.backup";

    /**
     * 枚举类目录
     */
    @Setter
    private String enum_folder = "com.pucong.gitee.database.backup";

    /**
     * 正则匹配字段注释对应的数据字典code
     * #code{}
     */
    private static Pattern DICT_CODE_PATTERN = Pattern.compile("#code\\{[\\w]*\\}");

    /**
     * 数据库连接
     */
    private final String URL = "jdbc:h2:file:./data/h2db/back_up;MODE=PostgreSQL;AUTO_SERVER=true";
    private final String USER = "sa";
    private final String PASSWORD = "sa";
    private final String DRIVER = "org.h2.Driver";

    /**
     * 输出设置
     */
    private String workSpace = new String();
    private String modelPath = new String();
    private String modelPath2 = new String();
    private String entityPathPoint = new String();
    private String businessPathPoint = new String();
    private String modulePathPoint = new String();
    private String modulePath = new String();
    private String entityPathReplace = new String();
    private String businessPathReplace = new String();
    private StringBuffer entityPath = new StringBuffer();
    private StringBuffer enumPath = new StringBuffer();
    private StringBuffer businessPath = new StringBuffer();
    private StringBuffer entityPackagePath = new StringBuffer();
    private StringBuffer businessPackagePath = new StringBuffer();
    private StringBuffer entityOtherImport = new StringBuffer();
    private String nowTime = new String();
    private String tableId = new String();
    private String tableIdUpper = new String();
    private String tableNameComment = new String();

    private Connection getConnection() throws Exception {
        Class.forName(DRIVER);
        Connection connection = DriverManager.getConnection(URL, USER, PASSWORD);
        return connection;
    }



    public void generate() {
        logger.info("开始执行自动生成工具");
        Connection connection = null;
        Statement statement = null;
        try {
            //初始化数据
            initData();
            //获取数据库连接
            connection = getConnection();
            logger.info("获取数据库连接成功");
            statement = connection.createStatement();
            //查询主键信息
            getTableIdInfo(statement);
            //查询表注释
            getTableComment(statement);
            //查询列信息和注释
            Map<String, Object> dataMap = getTableFiledList(statement);
            //获取列注释中枚举类信息
            if(runEntity){
                //生成枚举类
                generateEnumFile(statement,dataMap);
                //生成Model文件
                generateModelFile(dataMap);
                // 生成ModelVo文件
                generateModelVoFile(dataMap);
                // 生成ModelDto文件
                generateModelDtoFile(dataMap);
            }
            //生成Mapper文件
            if(runMapper){
                generateMapperFile(dataMap);
                //生成Mapper xml文件
                generateMapperXmlFile(dataMap);
            }
            //生成service接口类
            if(runService){
                generateServiceInterfaceFile(dataMap);
                //生成service接口实现类
                generateServiceImplFile(dataMap);
            }
            //生成Controller层文件
            if(runController){
                generateControllerFile(dataMap);
            }
            //生成runBeanConvert文件
            if(runBeanConvert){
                generateBeanCovertFile(dataMap);
            }
            //生成runBeanConvert文件
            if(runWebVue){
                generateWebVueFile(dataMap);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            try {
                if (connection != null) {
                    connection.close();
                }
                if (statement != null) {
                    statement.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
                logger.error("关闭失败");
            }
        }
        logger.info("执行结束！");
    }

    /**
     * 生成枚举类
     * @param dataMap
     */
    private void generateEnumFile(Statement statement,Map<String,Object> dataMap) throws Exception {

        List<TableColumn> modelColumn = (List<TableColumn>)dataMap.get("modelColumn");
        if(modelColumn != null && modelColumn.size()>0){
            logger.info("-----------开始生成枚举类------------");
            for(TableColumn tableColumn : modelColumn){
                //获取数据字典的值
                selectTableColumnEnumList(statement,tableColumn);

                List<TableColumnEnum> tableColumnEnumList = tableColumn.getTableColumnEnumList();
                if(tableColumnEnumList != null && tableColumnEnumList.size()>0){

                    dataMap.put("tableColumn",tableColumn);
                    dataMap.put("tableColumnEnumList",tableColumnEnumList);

                    final String suffix = ".java";
                    final String path = enumPath + "//" + tableColumn.getChangeEnumCode() + suffix;
                    final String templateName = "Enum.ftl";
                    entityOtherImport.append("import com.hchl.org.bpm.online.form.common.enumSelf."+ tableColumn.getChangeEnumCode() +";\n");
                    logger.info("生成枚举类文件地址：" + path);
                    File mapperFile = new File(path);
                    //创建目录
                    mkdirByParentFile(mapperFile);
                    //生成模板
                    generateFileByTemplate(templateName, mapperFile, dataMap);
                }
            }
        }
    }

    private Map<String, Object> getTableFiledList(Statement statement) throws SQLException {
        List<TableColumn> columnClassList = new ArrayList<>();
        TableColumn columnClass = null;
        String sql = "SELECT DISTINCT a.attnum as index, " +
                "a.attname AS field, " +
                "t.typname AS type, " +
                "b.description AS comment " +
                "FROM pg_class c,pg_attribute a " +
                "LEFT OUTER JOIN pg_description b ON a.attrelid=b.objoid AND a.attnum = b.objsubid,pg_type t " +
                "WHERE c.relname = '"+ table_name +"' " +
                "and a.attnum > 0 " +
                "and a.attrelid = c.oid " +
                "and a.atttypid = t.oid ";
        ResultSet resultSet = statement.executeQuery(sql);
        while (resultSet.next()) {
            columnClass = new TableColumn();
            //排序号
            String sortIndex = resultSet.getString("index");
            columnClass.setSortIndex(Integer.parseInt(sortIndex));
            //获取字段名称
            columnClass.setColumnName(resultSet.getString("field"));
            //获取字段类型
            columnClass.setColumnType(resultSet.getString("type"));
            //转换字段名称，如 sys_name 变成 SysName
            columnClass.setChangeColumnName(replaceUnderLineAndUpperCase(resultSet.getString("field")));
            //字段在数据库的注释
            columnClass.setColumnComment(resultSet.getString("comment"));
            if(tableId.equals(columnClass.getColumnName())){
                columnClass.setIsId(true);
            }else{
                columnClass.setIsId(false);
            }
            //没有列的注释
            if(StringUtils.isBlank(columnClass.getColumnComment())){
                throw new RuntimeException("列的注释为空！" + columnClass.getColumnName());
            }
            columnClassList.add(columnClass);
            if("date".equals(columnClass.getColumnType()) || "timestamp".equals(columnClass.getColumnType())){
                entityOtherImport.append("import java.util.Date;\n");
            }
            if("numeric".equals(columnClass.getColumnType()) || "decimal".equals(columnClass.getColumnType())){
                entityOtherImport.append("import java.math.BigDecimal;\n");
            }
        }
        //排序
        columnClassList.sort((TableColumn tab1,TableColumn tab2) -> tab1.getSortIndex() >= tab2.getSortIndex() ? 1 : -1);
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("modelColumn", columnClassList);
        return dataMap;
    }

    /**
     * 获取数据字典数据
     * @param tableColumn
     * @return
     */
    private void selectTableColumnEnumList(Statement statement,TableColumn tableColumn) throws SQLException {
        String columnComment = tableColumn.getColumnComment();
        List<TableColumnEnum> tableColumnEnumList = new ArrayList<>();
        String code = getDictCode(columnComment);
        if(StringUtils.isNotBlank(code)){
            String sql = "SELECT " +
                    "a.name as name, " +
                    "a.code as code, " +
                    "a.key  as key, " +
                    "a.value as value " +
                    "FROM ldp_sys_dict a " +
                    "where 1=1 " +
                    "and a.code='"+ code +"' " +
                    "and a.KEY is not null " +
                    "order by a.create_time desc";
            ResultSet resultSetTwo = statement.executeQuery(sql);
            int index = 0;
            while (resultSetTwo.next()) {
                TableColumnEnum tableColumnEnum = new TableColumnEnum();
                //排序号
                String name = resultSetTwo.getString("name");
                String key = resultSetTwo.getString("key");
                String value = resultSetTwo.getString("value");

                tableColumnEnum.setName(name);
                tableColumnEnum.setParentCode(code);
                tableColumnEnum.setDescription(key);
                tableColumnEnum.setValue(key);
                tableColumnEnum.setCode(value);
                tableColumnEnum.setIndex(index);
                tableColumnEnumList.add(tableColumnEnum);
                index++;
            }
            if(tableColumnEnumList.size()>0){
                String changeEnumCode = replaceUnderLineAndUpperCase(code);
                tableColumn.setColumnEnumName(tableColumnEnumList.get(0).getName());
                tableColumn.setChangeEnumCode(changeEnumCode);
                tableColumn.setTableColumnEnumList(tableColumnEnumList);
                tableColumn.setColumnType("enum");
            }
        }
    }

    /**
     * 获取数据字典code
     * @param columnComment
     * @return
     */
    private static String getDictCode(String columnComment) {
        Matcher matcher = DICT_CODE_PATTERN.matcher(columnComment);
        if(matcher.find()){
            String e = matcher.group();
            //进行替换
            String sqlFragment = e.replace("#code{", "");
            sqlFragment = sqlFragment.replace("}", "");
            return sqlFragment;
        }
        return "";
    }

    private void initData() {
        //必填项校验
        if (StringUtils.isBlank(change_table_name) || StringUtils.isBlank(author)
                || StringUtils.isBlank(table_name) || StringUtils.isBlank(module_path)) {
            throw new RuntimeException("请输入正确的参数author、change_table_name、model_name、table_name");
        }
        //判断实体类名首字母是否大写
        if (change_table_name.charAt(0) >= 'a' && change_table_name.charAt(0) <= 'z') {
            throw new RuntimeException("请输入正确的实体类名，首字母大写");
        }
        workSpace = System.getProperty("user.dir");
        modulePath = module_path.replace(".", "//");
        entityPathReplace = entity_package_folder.replace(".","//");
        businessPathReplace = business_package_folder.replace(".","//");
        modelPath = business_package_folder.replace(".","/");
        modelPath2 = modelPath.replace("/","//");
        entityPathPoint = entity_package_folder.replace("/",".");
        businessPathPoint = business_package_folder.replace("/",".");
        modulePathPoint = module_path.replace("/",".");
        enum_folder = enum_folder.replace(".", "//");
        entityPath.append(workSpace)
                .append("//src//main//java//")
                .append(modulePath + "//" + entityPathReplace + "//" + businessPathReplace);
        enumPath.append(workSpace)
                .append("//src//main//java//")
                .append(modulePath + "//" + enum_folder.replace(".","/"));
        businessPath.append(workSpace)
                .append("//src//main//java//")
                .append(modulePath + "//" + businessPathReplace);

        entityPackagePath.append(modulePathPoint + "." + entityPathPoint + "." + businessPathPoint);
        businessPackagePath.append(modulePathPoint + "." + business_package_folder);
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        nowTime = df.format(new Date());
    }

    /**
     * 生成实体类
     *
     * @param dataMap
     * @throws Exception
     */
    private void generateModelFile(Map<String, Object> dataMap) throws Exception {
        logger.info("-----------开始生成实体类------------");
        final String suffix = ".java";
        final String path = entityPath + "//" + change_table_name + suffix;
        final String templateName = "Model.ftl";
        logger.info("生成实体类文件地址：" + path);
        File mapperFile = new File(path);
        //创建目录
        mkdirByParentFile(mapperFile);

        generateFileByTemplate(templateName, mapperFile, dataMap);
    }

    /**
     * 生成实体类
     *
     * @param dataMap
     * @throws Exception
     */
    private void generateModelVoFile(Map<String, Object> dataMap) throws Exception {
        logger.info("-----------开始生成Vo类------------");
        final String suffix = ".java";
        final String path = entityPath + "//" + change_table_name+ "Vo" + suffix;
        final String templateName = "ModelVo.ftl";
        logger.info("生成Vo类文件地址：" + path);
        File mapperFile = new File(path);
        //创建目录
        mkdirByParentFile(mapperFile);

        generateFileByTemplate(templateName, mapperFile, dataMap);
    }

    /**
     * 生成实体类
     *
     * @param dataMap
     * @throws Exception
     */
    private void generateModelDtoFile(Map<String, Object> dataMap) throws Exception {
        logger.info("-----------开始生成Dto类------------");
        final String suffix = ".java";
        final String path = entityPath + "//" + change_table_name+ "UpdateDto" + suffix;
        final String path2 = entityPath + "//" + change_table_name+ "SelectDto" + suffix;
        final String path3 = entityPath + "//" + change_table_name+ "InsertDto" + suffix;
        final String templateName = "ModelUpdateDto.ftl";
        final String templateName2 = "ModelSelectDto.ftl";
        final String templateName3 = "ModelInsertDto.ftl";
        logger.info("生成Dto类文件地址：" + path);
        File mapperFile = new File(path);
        File mapperFile2 = new File(path2);
        File mapperFile3 = new File(path3);
        //创建目录
        mkdirByParentFile(mapperFile);
        mkdirByParentFile(mapperFile2);
        mkdirByParentFile(mapperFile3);

        generateFileByTemplate(templateName, mapperFile, dataMap);
        generateFileByTemplate(templateName2, mapperFile2, dataMap);
        generateFileByTemplate(templateName3, mapperFile3, dataMap);
    }

    /**
     * 生成实体类
     *
     * @param dataMap
     * @throws Exception
     */
    private void generateBeanCovertFile(Map<String, Object> dataMap) throws Exception {
        logger.info("-----------开始生成vo/do/dto转换类------------");
        final String suffix = ".java";
        final String path = businessPath + "//convert//" + change_table_name+"BeanConvert"+ suffix;
        final String templateName = "BeanConvert.ftl";
        logger.info("生成转换类文件地址：" + path);
        File mapperFile = new File(path);
        //创建目录
        mkdirByParentFile(mapperFile);

        generateFileByTemplate(templateName, mapperFile, dataMap);
    }

    /**
     * 生成控制器
     * @throws Exception
     */
    private void generateControllerFile(Map<String, Object> dataMap) throws Exception {
        logger.info("-----------生成控制器------------");
        final String suffix = "Controller.java";
        final String path = businessPath + "//controller//" + change_table_name + suffix;
        final String templateName = "Controller.ftl";
        logger.info("生成控制器地址：" + path);
        File mapperFile = new File(path);
        //创建目录
        mkdirByParentFile(mapperFile);
        generateFileByTemplate(templateName, mapperFile, dataMap);
    }

    /**
     * 生成service实现类
     * @throws Exception
     */
    private void generateServiceImplFile( Map<String, Object> dataMap) throws Exception {
        logger.info("-----------生成service实现类------------");
        final String suffix = "ServiceImpl.java";
        final String path = businessPath + "//service//" + change_table_name + suffix;
        final String templateName = "ServiceImpl.ftl";
        logger.info("生成service实现类地址：" + path);
        File mapperFile = new File(path);
        //创建目录
        mkdirByParentFile(mapperFile);
        generateFileByTemplate(templateName, mapperFile, dataMap);
    }

    /**
     * 生成service接口类
     * @throws Exception
     */
    private void generateServiceInterfaceFile(Map<String, Object> dataMap) throws Exception {
        logger.info("-----------生成service接口类------------");
        final String suffix = "Service.java";
        final String path = businessPath + "//service//" + change_table_name + suffix;
        final String templateName = "Service.ftl";
        logger.info("生成service接口类地址：" + path);
        File mapperFile = new File(path);
        //创建目录
        mkdirByParentFile(mapperFile);
        generateFileByTemplate(templateName, mapperFile, dataMap);
    }

    /**
     * 生成Mapper文件
     * @throws Exception
     */
    private void generateMapperFile(Map<String, Object> dataMap) throws Exception {
        logger.info("-----------开始生成mapper文件------------");
        final String suffix = "Mapper.java";
        final String path = businessPath+ "//mapper//" + change_table_name + suffix;
        final String templateName = "Mapper.ftl";
        logger.info("生成mapper文件地址：" + path);
        File mapperFile = new File(path);
        //创建目录
        mkdirByParentFile(mapperFile);
        generateFileByTemplate(templateName, mapperFile, dataMap);
    }

    /**
     * 生成Mapper XML文件
     * @throws Exception
     */
    private void generateMapperXmlFile(Map<String, Object> dataMap) throws Exception {
        logger.info("-----------开始生成mapper xml文件------------");
        final String suffix = "Mapper.xml";
        final String path = businessPath+ "//mapper//" + change_table_name + suffix;
        final String templateName = "MapperXml.ftl";
        logger.info("生成mapper xml文件地址：" + path);
        File mapperFile = new File(path);
        //创建目录
        mkdirByParentFile(mapperFile);
        generateFileByTemplate(templateName, mapperFile, dataMap);
    }

    /**
     * 生成前端代码
     *
     * @param dataMap
     * @throws Exception
     */
    private void generateWebVueFile(Map<String, Object> dataMap) throws Exception {
        logger.info("-----------开始生成vue web file------------");
        final String suffix = ".js";
        final String path = workSpace + "//data//tmp//" + change_table_name+ suffix;
        final String templateName = "VueWeb.ftl";
        logger.info("生成web vue文件地址：" + path);
        File mapperFile = new File(path);
        //创建目录
        mkdirByParentFile(mapperFile);

        generateFileByTemplate(templateName, mapperFile, dataMap);
    }
    /**
     * 如果目录不存在，则新建目录
     * @param mapperFile
     */
    private void mkdirByParentFile(File mapperFile){
        //判断父目录路径是否存在，即test.txt前的
        try {
            if(mapperFile.exists()){
                logger.info("该文件已存在将覆盖,path：" + mapperFile.getPath());
            }
            //不存在则创建父目录
            if (!mapperFile.getParentFile().exists()) {
                mapperFile.getParentFile().mkdirs();
                mapperFile.createNewFile();
            }
            if (!mapperFile.getParentFile().getParentFile().exists()) {
                mapperFile.getParentFile().getParentFile().mkdirs();
            }
        } catch (IOException e) {
            logger.error("创建目录失败",e);
        }
    }

    /**
     * 渲染模板
     * @param templateName
     * @param file
     * @param dataMap
     * @throws Exception
     */
    private void generateFileByTemplate(final String templateName, File file, Map<String, Object> dataMap) throws Exception {
        Template template = FreeMarkerTemplateUtils.getTemplate(templateName);
        FileOutputStream fos = new FileOutputStream(file);
        dataMap.put("tableIdUpper", tableIdUpper);
        dataMap.put("tableName", table_name);
        dataMap.put("tableNameComment", tableNameComment);
        dataMap.put("changeTableName", change_table_name);
        dataMap.put("modelPath", modelPath);
        dataMap.put("modelPathPoint", entityPathPoint);
        dataMap.put("author", author);
        dataMap.put("date", nowTime);
        dataMap.put("businessPackagePath", businessPackagePath);
        dataMap.put("entityPackagePath", entityPackagePath);
        dataMap.put("entityOtherImport", entityOtherImport);
        dataMap.put("tableAnnotation", tableAnnotation);
        dataMap.put("modulePath", modulePathPoint);
        dataMap.put("serviceName", serviceName);
        dataMap.put("baseUrl", "${baseUrl}");
        dataMap.put("pageNum", "${option.pageNum}");
        dataMap.put("pageSize", "${option.pageSize}");
        dataMap.put("optionId", "${option.id}");
        Writer out = new BufferedWriter(new OutputStreamWriter(fos, StandardCharsets.UTF_8), 10240);
        template.process(dataMap, out);
        //关闭流
        out.flush();
        out.close();
    }

    /**
     * _转化为驼峰
     *
     * @param str
     * @return
     */
    private String replaceUnderLineAndUpperCase(String str) {
        StringBuffer sb = new StringBuffer();
        sb.append(str);
        int count = sb.indexOf("_");
        while (count != 0) {
            int num = sb.indexOf("_", count);
            count = num + 1;
            if (num != -1) {
                char ss = sb.charAt(count);
                char ia = (char) (ss - 32);
                sb.replace(count, count + 1, ia + "");
            }
        }
        String result = sb.toString().replaceAll("_", "");
        return StringUtils.capitalize(result);
    }

    /**
     * 获取表的注释
     */
    private void getTableComment(Statement statement) {
        try {
            String sql = "SELECT  DISTINCT  " +
                    "obj_description(b.relfilenode,'pg_class') as tableComment " +
                    "FROM   pg_tables  a, pg_class b " +
                    "WHERE    " +
                    "a.tablename = b.relname " +
                    "and " +
                    "a.tablename = '"+ table_name +"'";
            ResultSet resultSetTableConment = statement.executeQuery(sql);
            while (resultSetTableConment.next()) {
                tableNameComment = resultSetTableConment.getString("tableComment");
                if(StringUtils.isBlank(tableAnnotation)){
                    tableAnnotation = tableNameComment;
                }
                logger.info(table_name+"表注释："+tableNameComment);
                break;
            }
            //没有表的注释
            if(StringUtils.isBlank(tableAnnotation)){
                throw new RuntimeException("表注释和描述都为空！");
            }
        } catch (SQLException e) {
            logger.error("获取表注释失败",e);
        }
    }

    /**
     * 获取表的主键信息
     * @param statement
     */
    private void getTableIdInfo(Statement statement) {
        try {
            ResultSet resultSetTableIdConment = statement.executeQuery("select DISTINCT pg_attribute.attname as colname,pg_type.typname as typename,pg_constraint.conname as pk_name  " +
                    "from pg_constraint  inner join pg_class  " +
                    "on pg_constraint.conrelid = pg_class.oid  " +
                    "inner join pg_attribute on pg_attribute.attrelid = pg_class.oid  " +
                    "and  pg_attribute.attnum = pg_constraint.conkey[1] " +
                    "inner join pg_type on pg_type.oid = pg_attribute.atttypid " +
                    "where pg_class.relname = '"+ table_name +"' " +
                    "and pg_constraint.contype='p'");
            while (resultSetTableIdConment.next()) {
                tableId = resultSetTableIdConment.getString("colname");
                tableIdUpper = replaceUnderLineAndUpperCase(tableId);
                logger.info(table_name+"表主键："+tableId);
                break;
            }
        } catch (SQLException e) {
            logger.error("获取表获取主键失败",e);
        }
        if(StringUtils.isBlank(tableId)){
            throw new RuntimeException("不存在主键信息，请添加主键");
        }
    }

}
